package com.tomecode.tools.maven.settings.gui.tabs;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;

import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;

import com.tomecode.tools.maven.settings.SettingsFactory;
import com.tomecode.tools.maven.settings.gui.FrmListOfProfiles;
import com.tomecode.tools.maven.settings.model.Profile;
import com.tomecode.tools.maven.settings.model.Settings;
import com.tomecode.util.gui.HideNotifiListener;
import com.tomecode.util.gui.PanelFactory;
import com.tomecode.util.gui.component.Button;

/**
 * 
 * Basic tab
 * 
 * @author Frastia Tomas
 * 
 */
public class BasicTab extends JPanel {

	private static final long serialVersionUID = 4423551210879365383L;

	private File lastSelectedFolder;

	private final JTextField txtLocalRepository;

	private final JCheckBox checkInteractiveMode;

	private final JCheckBox checkUsePluginRegistry;

	private final JCheckBox checkOffline;

	private final JTable tableActiveProfiles;

	private final ActiveProfilesModel tableActiveProfilesModel;

	private final Button bRemove;
	private final Button bAdd;
	private final Button bFind;

	private Settings settings;

	public BasicTab(Settings sett) {
		setLayout(new BorderLayout());
		setBorder(new EmptyBorder(10, 10, 10, 10));
		// setBorder(new TitledBorder(""));
		settings = sett;

		tableActiveProfilesModel = new ActiveProfilesModel(settings);
		tableActiveProfiles = new JTable(tableActiveProfilesModel);

		tableActiveProfiles.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				selectInTable(tableActiveProfiles.getSelectedRow());
			}

		});
		tableActiveProfiles.addMouseListener(new MouseAdapter() {
			public final void mouseClicked(MouseEvent e) {
				selectInTable(tableActiveProfiles.getSelectedRow());
			}
		});

//		TableColumnModel tableColumnModel = tableActiveProfiles.getColumnModel();
//		tableColumnModel.getColumn(tableColumnModel.getColumnCount() - 1).setMaxWidth(66);

		bAdd = new Button("Add", new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				FrmListOfProfiles.showMe(settings.getActiveProfiles(), settings.getProfiles(), new HideNotifiListener() {
					public final void hideForm(Object profile) {
						tableActiveProfilesModel.add((Profile) profile);
					}
				});
			}
		});

		bRemove = new Button("Del", false, new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				if (tableActiveProfiles.getSelectedRow() == -1) {
					return;
				}
				tableActiveProfilesModel.remove(tableActiveProfiles.getSelectedRow());
				disableTableButtons();
			}
		});

		txtLocalRepository = new JTextField(settings.getLocalRepository());
		txtLocalRepository.setName(SettingsFactory.E_LOCAL_REPOSITORY);
		txtLocalRepository.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				settings.setLocalRepository(txtLocalRepository.getText());
			}
		});

		checkInteractiveMode = new JCheckBox("Interactive Mode", settings.isInteractiveMode());
		checkInteractiveMode.setName(SettingsFactory.E_INTERACTIVE_MODE);
		checkInteractiveMode.addActionListener(new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				settings.setInteractiveMode(((JCheckBox) e.getSource()).isSelected());
			}
		});

		checkUsePluginRegistry = new JCheckBox("Use Plugin Registry", settings.isUsePluginRegistry());
		checkUsePluginRegistry.setName(SettingsFactory.E_USE_PLUGIN_REGISTRY);
		checkUsePluginRegistry.addActionListener(new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				settings.setUsePluginRegistry(((JCheckBox) e.getSource()).isSelected());
			}
		});
		checkOffline = new JCheckBox("Offline", settings.isOffline());
		checkOffline.setName(SettingsFactory.E_OFFLINE);
		checkOffline.addActionListener(new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				settings.setOffline(((JCheckBox) e.getSource()).isSelected());
			}
		});

		JPanel pWrapRepository = PanelFactory.createBorderLayout(0, 0, 0, 0);
		pWrapRepository.add(PanelFactory.wrapWithLabelNorm("Local Repository", txtLocalRepository, 10), BorderLayout.CENTER);
		JPanel pWrapRepositoryButt = PanelFactory.createBorderLayout(0, 0, 0, 0);

		bFind = new Button("...", new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				chooseFile();
			}
		});
		bFind.setPreferredSize(new Dimension(30, 20));
		pWrapRepositoryButt.setPreferredSize(new Dimension(70, 10));

		pWrapRepositoryButt.add(PanelFactory.wrapByBorderLayout(bFind, BorderLayout.NORTH), BorderLayout.CENTER);
		pWrapRepositoryButt.add(wrapPanelToCommentAndNotShow(SettingsFactory.E_LOCAL_REPOSITORY, settings.isCommented(txtLocalRepository.getName()), settings.isDeleted(txtLocalRepository.getName())), BorderLayout.EAST);
		pWrapRepository.add(pWrapRepositoryButt, BorderLayout.EAST);

		JPanel pWrap = PanelFactory.createBorderLayout(0, 0, 0, 0);
		JPanel txtPanel = PanelFactory.createGridLayout(4, 1);
		txtPanel.add(pWrapRepository);
		txtPanel.add(wrapPanelWithCheckBoxOnRight(checkInteractiveMode, settings.isCommented(checkInteractiveMode.getName()), settings.isDeleted(checkInteractiveMode.getName())));
		txtPanel.add(wrapPanelWithCheckBoxOnRight(checkUsePluginRegistry, settings.isCommented(checkUsePluginRegistry.getName()), settings.isDeleted(checkUsePluginRegistry.getName())));
		txtPanel.add(wrapPanelWithCheckBoxOnRight(checkOffline, settings.isCommented(checkOffline.getName()), settings.isDeleted(checkOffline.getName())));

		pWrap.add(txtPanel, BorderLayout.NORTH);

		JPanel pTable = PanelFactory.createBorderLayout(0, 0, 0, 0);
		pTable.add(new JScrollPane(tableActiveProfiles), BorderLayout.CENTER);
		JPanel pTableButt = PanelFactory.createGridLayout(3, 1);
		pTableButt.add(bAdd);
		pTableButt.add(bRemove);

		JPanel pTableButtWrap = PanelFactory.createBorderLayout(0, 0, 0, 0);
		pTableButtWrap.add(pTableButt, BorderLayout.NORTH);
		pTable.add(pTableButtWrap, BorderLayout.EAST);
		pWrap.add(PanelFactory.wrapWithTile("Active Profiles", pTable), BorderLayout.CENTER);
		add(pWrap, BorderLayout.CENTER);
	}

	/**
	 * create {@link JPanel} with {@link JCheckBox} for comment and for delele
	 * 
	 * @param component
	 * @param isCommented
	 * @param isDeleted
	 * @return
	 */
	public final JPanel wrapPanelWithCheckBoxOnRight(JComponent component, boolean isCommented, boolean isDeleted) {
		JPanel panel = PanelFactory.createBorderLayout(0, 0, 0, 0);
		panel.add(component, BorderLayout.CENTER);
		panel.add(wrapPanelToCommentAndNotShow(component.getName(), !isCommented, !isDeleted), BorderLayout.EAST);
		return panel;
	}

	/**
	 * panel contains all checkbox for comment and display in xml
	 * 
	 * @param name
	 * @return
	 */
	private final JPanel wrapPanelToCommentAndNotShow(String name, boolean isCommented, boolean isDeleted) {
		JPanel panel = PanelFactory.createGridLayout(1, 1);
		final JCheckBox checkComment = new JCheckBox();
		checkComment.setSelected(isCommented);
		checkComment.setActionCommand(name);
		checkComment.setToolTipText("for comment");
		checkComment.addActionListener(new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				JCheckBox check = (JCheckBox) e.getSource();
				setCheckCommentedStatus(check.getActionCommand(), check.isSelected());
			}
		});

		
		//TODO: temporary commented panel.add(checkComment);
		JCheckBox checkShow = new JCheckBox();
		checkShow.setSelected(isDeleted);
		checkShow.setActionCommand(name);
		checkShow.setToolTipText("for display");
		checkShow.addActionListener(new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				JCheckBox check = (JCheckBox) e.getSource();
				setCheckDeleteStatus(check.getActionCommand(), check.isSelected());
				checkComment.setEnabled(check.isSelected());
			}
		});

		setCheckDeleteStatus(name, isDeleted);
		if (!isDeleted) {
			checkComment.setEnabled(isDeleted);
		}
		panel.add(checkShow);
		return panel;
	}

	/**
	 * set enable/disable for checkbox
	 * 
	 * @param name
	 * @param state
	 */
	private final void setCheckCommentedStatus(String name, boolean state) {
		if (state) {
			settings.setCommented(name);
		} else {
			settings.removeCommented(name);
		}
	}

	/**
	 * set enable/disable for checkbox
	 * 
	 * @param name
	 * @param state
	 */
	private final void setCheckDeleteStatus(String name, boolean state) {
		if (name.equals(checkInteractiveMode.getName())) {
			checkInteractiveMode.setEnabled(state);
		} else if (name.equals(checkUsePluginRegistry.getName())) {
			checkUsePluginRegistry.setEnabled(state);
		} else if (name.equals(checkOffline.getName())) {
			checkOffline.setEnabled(state);
		} else if (name.equals(txtLocalRepository.getName())) {
			txtLocalRepository.setEnabled(state);
			bFind.setEnabled(state);
		}

		if (state) {
			settings.removeDeleted(name);
		} else {
			settings.setDeleted(name);
		}
	}

	/**
	 * select in table
	 * 
	 * @param selectedRow
	 */
	private final void selectInTable(int selectedRow) {
		if (selectedRow == -1) {
			disableTableButtons();
			return;
		}

		bRemove.setEnabled(true);
	}

	private final void disableTableButtons() {
		bRemove.setEnabled(false);
	}

	/**
	 * open {@link JFileChooser} and set selected path to
	 * {@link #txtLocalRepository}
	 */
	private final void chooseFile() {
		final JFileChooser fc = (lastSelectedFolder == null) ? new JFileChooser() : new JFileChooser(lastSelectedFolder.getPath());
		fc.setMultiSelectionEnabled(false);
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int returnVal = fc.showOpenDialog(this);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			lastSelectedFolder = fc.getSelectedFile().getParentFile();
			txtLocalRepository.setText(fc.getSelectedFile().getPath());
			settings.setLocalRepository(txtLocalRepository.getText());
		}
	}

	/**
	 * 
	 * 
	 * Active profiles {@link JTable} data model
	 * 
	 * 
	 * @author Frastia Tomas
	 * 
	 */
	private final class ActiveProfilesModel extends AbstractTableModel {

		private static final long serialVersionUID = 7027797033397340585L;

		private final String[] columns = new String[] { "Profile"};//, "Comment" };

		private final Settings settings;

		private ActiveProfilesModel(Settings settings) {
			this.settings = settings;
		}

		private final void add(Profile profile) {
			if (profile == null) {
				return;
			}
			this.settings.addActiveProfile(profile.getId());
			fireTableDataChanged();
		}

		/**
		 * remove active profiles
		 * 
		 * @param index
		 */
		private final void remove(int index) {
			this.settings.getActiveProfiles().remove(index);
			fireTableDataChanged();
		}

		public final String getColumnName(int column) {
			return columns[column];
		}

		public final Class<?> getColumnClass(int columnIndex) {
			return columnIndex == 0 ? String.class : Boolean.class;
		}

		public final boolean isCellEditable(int rowIndex, int columnIndex) {
			return (columnIndex != 0);
		}

		public final int getColumnCount() {
			return columns.length;
		}

		public final int getRowCount() {
			return this.settings.getActiveProfiles().size();
		}

		public final Object getValueAt(int rowIndex, int columnIndex) {
			String activeProfile = this.settings.getActiveProfiles().get(rowIndex);
			if (columnIndex == 0) {
				return activeProfile;
			}
			return false;

			// Profile profile = this.settings.getProfiles().get(rowIndex);
			// if (columnIndex == 1) {
			// return profile.getId();
			// } else if (columnIndex == 0) {
			// return this.settings.isActiveProfile(profile.getId());
			// }
			// return false;
		}

		public final void setValueAt(Object aValue, int rowIndex, int columnIndex) {
			// Profile profile = settings.getProfiles().get(rowIndex);
			// if (columnIndex == 0) {
			// boolean b = (Boolean) aValue;
			// if (b) {
			// settings.addActiveProfile(profile.getId());
			// } else {
			// settings.removeActiveProfile(profile.getId());
			// }
			// }
		}
	}
}
